package com.iatinspur.dubbo.test;

import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.rpc.service.GenericService;
import java.util.HashMap;
import java.util.Map;

/**
 * 这个环境 没有Dubbo的注册接口 没有Dubbo的pojo
 * 尝试的情况是
 * 1.走dubbo【直调】
 * 2.走nacos
 * 3.走zookeeper
 * 4.使用rpc协议
 * 6.了解dubbo的泛化调用
 * 【这里的核心类 GenericService】
 */
public class ConsumerDoProvider {

    /**
     *   【GenericService】实际是 class com.alibaba.dubbo.rpc.service.GenericServiceDubboProxy0
     *
     * @param args
     */
    public static void main(String[] args) {

        // todo 调用【服务】60903、60904 zookeeper 2181 【启动前看看这东西有没有】
  //      doDubbo(getZookeeperGenericService(),"zookeeper");

        // todo 调用【服务】60905 【启动前看看这东西有没有】
        doDubbo(getDubboGenericService(),"dubbo");

        // todo 调用【服务】60905、60906 nacos 8848 【启动前看看这东西有没有】
    //    doDubbo(getNacosGenericService(),"nacos");

    }

    /**
     * 6.了解dubbo的泛化调用
     * @param service
     * @param name
     */
    public static void doDubbo(GenericService service,String name){
        /**
         * com.iatinspur.dubbo.service.ProviderService
         * 提供三个方法
         *     String getInfo();
         *     String detail(Person person);
         *     Person getPerson(Integer age);
         */
        Object getInfo = service.$invoke("getInfo", new String[]{}, new Object[]{});
        System.err.println("走【"+name+"】，调用无参方法【getInfo】");
        System.err.println(getInfo);


        Map<String,Object> map=new HashMap<>();
        // todo 注意:pojo 中的属性名要和 key一直
        map.put("name","雄霸");
        map.put("age",18);
        Object detail = service.$invoke("detail", new String[]{"com.iatinspur.pojo.Person"}, new Object[]{map});
        System.err.println("走【"+name+"】，调用参数【com.iatinspur.pojo.Person】，接口名称【detail】");
        System.err.println(detail);

        System.err.println("直走【"+name+"】，调用参数【java.lang.Integer】，接口名称【getPerson】");
        Object getPerson = service.$invoke("getPerson", new String[]{"java.lang.Integer"}, new Object[]{18});
        System.err.println(getPerson);
        System.err.println("方法【getPerson】的结果类型应该是【com.iatinspur.pojo.Person】，但是这里是【"+getPerson.getClass()+"】");

    }

    /**
     *  1.走dubbo【直调】 + 4.使用rpc协议
     * @return
     */
    private static GenericService getDubboGenericService() {
        /**
         *  <dubbo:application name="dubbo3.x-provider"/>
         *  详见dubbo配置文件
         *  直接走dubbo时，application name可以随便填写 但是必须得有
         *  无论连哪些dubbo 在程序没有关闭前  application name要一样
         */
        ApplicationConfig config=new ApplicationConfig("consumer-do-provider");
        // todo 这个是dubbo文件中的reference标签
        ReferenceConfig<GenericService> reference=new ReferenceConfig<>();
        /**
         * 详见这个标签
         * <dubbo:reference id="userAuthorityService" interface="com.iatinspur.dubbo.service.ProviderService" timeout="20000" group="bsp" check="false" url="dubbo://127.0.0.1:60905" version="0.0.1"/>
         */
        reference.setInterface("com.iatinspur.dubbo.service.ProviderService");
        reference.setVersion("1.0.0");
        reference.setUrl("dubbo://127.0.0.1:60905");
        reference.setProtocol("dubbo");
        reference.setApplication(config);
        // 使用泛型调用
        reference.setGeneric(true);
        return reference.get();
    }

    /**
     * 2.走nacos + 4.使用rpc协议
     * @return
     */
    private static GenericService getNacosGenericService() {
        /**
         *  <dubbo:application name="dubbo3.x-provider"/>
         *  详见dubbo配置文件
         *  直接走dubbo时，application name可以随便填写 但是必须得有
         */
        ApplicationConfig config=new ApplicationConfig("consumer-do-provider");
        // todo 这个是dubbo文件中的reference标签
        ReferenceConfig<GenericService> reference=new ReferenceConfig<>();

        /**
         *  注册中心nacos 设置
         */
        RegistryConfig registry = new RegistryConfig();
        registry.setAddress("nacos://127.0.0.1:8848");
        registry.setUsername("nacos");
        registry.setPassword("nacos");
        HashMap<String,String> map=new HashMap<>();
        map.put("namespace", "d3883ff7-0010-456e-bae2-01e37fc114f4");
        map.put("group", "dubbo3.x");
        registry.setRegister(false);
        registry.setParameters(map);

        /**
         * 详见这个标签
         * <dubbo:reference id="userAuthorityService" interface="com.iatinspur.dubbo.service.ProviderService" timeout="20000" group="bsp" check="false" url="dubbo://127.0.0.1:60905" version="0.0.1"/>
         */
        reference.setInterface("com.iatinspur.dubbo.service.ProviderService");
        reference.setVersion("1.0.0");
        reference.setProtocol("dubbo");
        reference.setRegistry(registry);
        reference.setApplication(config);
        // 使用泛型调用
        reference.setGeneric(true);
        return reference.get();
    }

    /**
     * 3。走zookeeper + 4.使用rpc协议
     * @return
     */
    private static GenericService getZookeeperGenericService() {
        /**
         *  <dubbo:application name="dubbo3.x-provider"/>
         *  详见dubbo配置文件
         *  直接走dubbo时，application name可以随便填写 但是必须得有
         *  无论连哪些dubbo 在程序没有关闭前  application name要一样
         */
        ApplicationConfig config=new ApplicationConfig("consumer-do-provider");
        // todo 这个是dubbo文件中的reference标签
        ReferenceConfig<GenericService> reference=new ReferenceConfig<>();

        /**
         *  注册中心nacos 设置
         */
        RegistryConfig registry = new RegistryConfig();
        registry.setAddress("zookeeper://127.0.0.1:2181");
        registry.setRegister(false);
        /**
         * 详见这个标签
         * <dubbo:reference id="userAuthorityService" interface="com.iatinspur.dubbo.service.ProviderService" timeout="20000" group="bsp" check="false" url="dubbo://127.0.0.1:60905" version="0.0.1"/>
         */
        reference.setInterface("com.iatinspur.dubbo.service.ProviderService");
        reference.setVersion("1.0.0");
        reference.setProtocol("dubbo");
        reference.setRegistry(registry);
        reference.setApplication(config);
        // 使用泛型调用
        reference.setGeneric(true);
        return reference.get();
    }

}
